// 导出一个函数，用于生成逻辑回归的训练数据
// 参数numSamples表示要生成的数据点总数
// 生成的数据是二维平面上的点，分为两个类别（标签0和标签1）
export function getData(numSamples) {
    // 用来存储所有数据点的数组
    let points = [];
  
    // 内部函数：生成符合高斯分布（正态分布）的数据点
    // cx, cy是中心点坐标，label是这些点的分类标签
    function genGauss(cx, cy, label) {
      // 为每个类别生成总样本数的一半
      for (let i = 0; i < numSamples / 2; i++) {
        // 生成围绕中心点cx的正态分布随机x坐标
        let x = normalRandom(cx);
        // 生成围绕中心点cy的正态分布随机y坐标
        let y = normalRandom(cy);
        // 把生成的点和标签一起存入数组
        points.push({ x, y, label });
      }
    }
  
    // 生成第一类数据：围绕点(2,2)的点，标签为1
    genGauss(2, 2, 1);
    // 生成第二类数据：围绕点(-2,-2)的点，标签为0
    genGauss(-2, -2, 0);
    // 返回生成的所有数据点
    return points;
  }
  
  /**
   * 生成服从正态分布的随机数
   * 使用Box-Muller变换算法
   *
   * @param mean 平均值，默认是0
   * @param variance 方差，默认是1
   */
  function normalRandom(mean = 0, variance = 1) {
    // 定义变量
    let v1, v2, s;
    
    // Box-Muller变换算法的核心部分
    // 生成两个在[-1,1]范围内的随机数
    // 确保这两个点在单位圆内（s <= 1）
    do {
      v1 = 2 * Math.random() - 1;
      v2 = 2 * Math.random() - 1;
      s = v1 * v1 + v2 * v2;
    } while (s > 1);
  
    // 应用Box-Muller变换公式，得到一个标准正态分布的随机数
    let result = Math.sqrt(-2 * Math.log(s) / s) * v1;
    
    // 根据提供的均值和方差调整结果
    // sqrt(variance)是标准差
    return mean + Math.sqrt(variance) * result;
  }